library ieee;
use ieee.std_logic_1164.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use ieee.numeric_std.all;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity sec_counter is
    generic (
        CYCLES_SEC : integer := 100e6;
        MAX_SECS_LOG2 : integer := 16
    );
    port (
        -- incoming control signals
        clk : in std_logic;
        res : in std_logic;

        -- outgoing signals
        tick     : out std_logic;
        cnt_secs : out integer
    );
end sec_counter;

architecture Behavioral of sec_counter is

    constant INITIAL_COUNT : integer := 0;

    signal cnt_ticks : integer := 0;

begin

    -- internal process
    count : process (all)
    begin
        -- default assignment
        cnt_ticks <= cnt_ticks;
        cnt_secs <= cnt_secs;

        if res = '1' then
            -- reset to some initial value on reset
            tick <= '0';
            cnt_ticks <= INITIAL_COUNT;
            cnt_secs <= INITIAL_COUNT;
        elsif rising_edge(clk) then
            -- second to second counter assignment
            if cnt_ticks = CYCLES_SEC then
                tick <= '1';
                cnt_ticks <= 0;
            -- increment counter and don't output tick before reaching CYCLES_SEC
            else
                tick <= '0';
                cnt_ticks <= cnt_ticks + 1;
            end if;

            -- higher tick counter (sec counter) assignment
            if tick = '1' and cnt_secs = (2**MAX_SECS_LOG2) then
                cnt_secs <= 0;
            elsif tick = '1' then
                cnt_secs <= cnt_secs + 1;
            end if;
        end if;
    end process;

end Behavioral;
